# -*- coding:utf-8 -*-
"""
@file       fangcheng.py
"""
from sympy import degree, tan
from sympy.abc import rho

from mathsolver.functions.base import *

_p_x = sympify("rho*cos(theta)")
_p_y = sympify("rho*sin(theta)")
_p_c_t = sympify("rho*cos(theta)")
_p_s_t = sympify("rho*sin(theta)")
_p_c = sympify("cos(theta)")
_p_s = sympify("sin(theta)")
_rho2 = rho ** 2


class JiConvertZhi(BaseFunction):  # 极坐标方程转化为直角坐标方程
    def solver(self, *args):  # in: BaseEq, out: BaseEq
        self.label.add("极坐标方程转化为直角坐标方程")
        th = Symbol("theta")
        left, right = args[0].sympify()
        left, right = left.expand(trig=True), right.expand(trig=True)
        poly = left - right
        self.steps.append(["", "令x = %s, y = %s" % (new_latex(_p_c_t), new_latex(_p_s_t))])
        if poly.coeff(_p_x) != 0 or poly.coeff(_p_y) != 0:
            poly = poly.subs({_p_x: x, _p_y: y, _rho2: x ** 2 + y ** 2})
        elif poly.coeff(_p_c) != 0 or poly.coeff(_p_s) != 0:
            poly = (rho * poly).expand(trig=True)
            poly = poly.subs({_p_x: x, _p_y: y, _rho2: x ** 2 + y ** 2})
        elif poly.coeff(rho) != 0:
            poly = poly.subs({rho: "sqrt(x**2+y**2)"})
        elif poly.coeff(th) != 0:
            a = poly.coeff(th) * th - poly
            poly = tan(a) * x - poly.coeff(th) * y
        else:
            raise ValueError()
        eq = BaseEq([poly.simplify(), 0])
        self.steps.append(["", "∴转化为直角坐标方程为:%s" % eq.printing()])
        self.output.append(BaseValue(eq.value))
        return self


class ZhiConvertJi(BaseFunction):  # 直角坐标方程转化为极坐标方程
    def solver(self, *args):  # in: BaseEq, out: BaseEq
        self.label.add("直角坐标方程转化为极坐标方程")
        left, right = args[0].sympify()
        poly = left - right
        self.steps.append(["", "令x = %s, y = %s" % (new_latex(_p_c_t), new_latex(_p_s_t))])
        sub_poly = poly.subs({x: _p_c_t, y: _p_s_t}).simplify()
        if sub_poly.is_Mul and rho in sub_poly.args:
            sub_poly = (sub_poly / rho).simplify().expand(trig=True)
        eq = BaseEq([sub_poly, 0])
        self.steps.append(["", "∴转化为极坐标方程为：%s" % eq.printing()])
        # self.output.append(baseValue(eq.value))
        return self


class CanConvertZhi(BaseFunction):  # 参数方程转化为直角坐标方程
    def solver(self, *args):  # in:BaseEqs, out:BaseEq
        self.label.add("参数方程转化为直角坐标方程")
        sym = args[1].sympify()
        eqs = []
        eqs_ind = []
        for left, right in args[0].sympify():
            poly = left - right
            eqs.append(poly)
            eqs_ind.append(poly.as_independent(sym)[1])
        try:
            wc = self.__which(eqs_ind[0], eqs_ind[1], sym)
            print(wc)
            if wc[0] == 1:
                dg_1 = degree(wc[1])
                dg_2 = degree(wc[2])
                if dg_1 == 1:
                    result = solve(eqs[0] / wc[3], wc[1], dict=True)[0]
                    rs = result[wc[1]]
                    self.steps.append(["", "由①得：%s = %s" % (new_latex(wc[1]), new_latex(rs))])
                    poly = eqs[1].subs({wc[1]: rs})
                    eq = BaseEq([poly, 0])
                    self.steps.append(["", "代入②得：%s" % eq.printing()])
                elif dg_2 == 1:
                    result = solve(eqs[1] / wc[4], wc[2], dict=True)[0]
                    rs = result[wc[2]]
                    self.steps.append(["", "由②得：%s = %s" % (new_latex(wc[2]), new_latex(rs))])
                    poly = eqs[0].subs({wc[2]: rs}).simplify()
                    eq = BaseEq([poly, 0])
                    self.steps.append(["", "代入①得：%s" % eq.printing()])
                else:
                    result = solve(eqs[0] / wc[3], sym, dict=True)[0]
                    rs = result[sym]
                    self.steps.append(["", "由①得：%s = %s" % (new_latex(sym), new_latex(rs))])
                    poly = (eqs[1] / wc[4]).subs({sym: rs})
                    eq = BaseEq([poly, 0])
                    self.steps.append(["", "代入②得：%s" % eq.printing()])
            elif wc[0] == 2:
                rs_c = solve(eqs[0], wc[1], dict=True)[0][wc[1]]
                rs_s = solve(eqs[1], wc[2], dict=True)[0][wc[2]]
                self.steps.append(["", "由①得：%s = %s" % (new_latex(wc[1]), new_latex(rs_c))])
                self.steps.append(["", "由②得：%s = %s" % (new_latex(wc[2]), new_latex(rs_s))])
                str_dp1 = str(wc[1])
                str_dp2 = str(wc[2])

                flag = []
                if "**2" in str_dp1:
                    flag.append(1)
                    fir = rs_c
                else:
                    if "sin" in str_dp1 or "cos" in str_dp1:
                        flag.append(1)
                        fir = rs_c ** 2
                    else:
                        flag.append(0)
                        fir = rs_c
                if "**2" in str_dp2:
                    flag.append(1)
                    sec = rs_s
                else:
                    if "sin" in str_dp2 or "cos" in str_dp2:
                        flag.append(1)
                        sec = rs_s ** 2
                    else:
                        flag.append(0)
                        sec = rs_s
                if sum(flag) == 0:
                    poly = simplify(fir - sec)
                    eq = BaseEq([poly, 0])
                else:
                    poly = simplify(fir + sec)
                    eq = BaseEq([poly, 1])
                self.steps.append(["", "∴得：%s" % eq.printing()])
            elif wc[0] == 3:
                rs_c = solve(eqs[0] / wc[3], wc[1], dict=True)[0][wc[1]]
                rs_s = solve(eqs[1] / wc[4], wc[2], dict=True)[0][wc[2]]
                self.steps.append(["", "由①得：%s = %s" % (new_latex(wc[1]), new_latex(rs_c))])
                self.steps.append(["", "由②得：%s = %s" % (new_latex(wc[2]), new_latex(rs_s))])
                if "**2" in str(wc[1]):
                    l_fir = rs_c
                    r_fir = wc[1]
                else:
                    l_fir = rs_c ** 2
                    r_fir = wc[1] ** 2
                if "**2" in str(wc[2]):
                    l_sec = rs_s
                    r_sec = wc[2]
                else:
                    l_sec = rs_s ** 2
                    r_sec = wc[2] ** 2
                poly_left = simplify(l_fir - l_sec)
                poly_right = simplify(r_fir - r_sec)
                eq = BaseEq([poly_left, poly_right])
                self.steps.append(["", "∴得：%s" % eq.printing()])
            else:
                raise

            self.output.append(BaseValue(eq.value))
        except Exception:
            self.steps.append(["", "对不起，该题型尚未支持！！！"])
        return self

    @staticmethod
    def __which(poly1, poly2, sym):  # 判断类型
        """
        1. at,bt
        2. acos(t), asin(t)
        3. at+b/t, at-b/t
        """
        poly1 = poly1.expand()
        poly2 = poly2.expand()
        if poly1.is_Add and poly2.is_Add:
            args_1_f, args_1_s = poly1.args
            args_2_f, args_2_s = poly2.args
            # 防止交换律的坑
            if args_1_f.as_powers_dict()[sym] < 0:
                args_1_f, args_1_s = args_1_s, args_1_f
            if args_2_f.as_powers_dict()[sym] < 0:
                args_2_f, args_2_s = args_2_s, args_2_f
            # 处理系数
            coef1, args_1_f = args_1_f.args
            args_1_s = args_1_s / coef1

            coef2, args_2_f = args_2_f.args
            args_2_s = args_2_s / coef2

            if (args_1_f == args_2_f and args_1_s == -args_2_s) or (args_1_f == -args_2_f and args_1_s == args_2_s):
                return 3, args_1_f + args_1_s, args_2_f + args_2_s, coef1, coef2
            elif args_1_f ** 2 == args_2_f and args_1_s ** 2 == args_2_s:
                return 3, args_1_f + args_1_s, args_2_f + args_2_s, coef1, coef2
            elif args_2_f ** 2 == args_1_f and args_2_s ** 2 == args_1_s:
                return 3, args_1_f + args_1_s, args_2_f + args_2_s, coef1, coef2
            elif args_1_f == args_2_f and args_1_s == args_2_s:
                return 1, args_1_f + args_1_s, args_2_f + args_2_s, coef1, coef2
            else:
                return 0
        else:
            str_poly_1 = str(poly1)
            str_poly_2 = str(poly2)
            coef1, dp1 = poly1.as_independent(sym)
            coef2, dp2 = poly2.as_independent(sym)
            if ("cos" in str_poly_1 and "sin" in str_poly_2) or ("sin" in str_poly_1 and "cos" in str_poly_2):
                return 2, dp1, dp2, coef1, coef2
            else:
                return 1, dp1, dp2, coef1, coef2


class JiZuoBiaoUpdate(BaseFunction):
    def solver(self, *args):
        args[0].value = args[1].value
        self.output.append(args[0])
        self.steps.append([args[0].printing(), ""])
        return self


if __name__ == '__main__':
    pass
